package com.leyou.user.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.RegexUtils;
import com.leyou.user.dto.UserDTO;
import com.leyou.user.entity.TbUser;
import com.leyou.user.mapper.TbUserMapper;
import com.leyou.user.service.TbUserService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.leyou.common.constants.MQConstants.Exchange.SMS_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.VERIFY_CODE_KEY;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author mybaitsplus
 * @since 2019-10-18
 */
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements TbUserService {

    @Override
    public Boolean checkData(String data, Integer type) {
        QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
        switch (type){
            case 1:
                queryWrapper.lambda().eq(TbUser::getUsername,data);
                break;
            case 2:
                queryWrapper.lambda().eq(TbUser::getPhone,data);
                break;
            default:
                throw  new LyException(ExceptionEnum.INVALID_PARAM_ERROR);
        }

        int count = this.count(queryWrapper);
        return count==0;
    }
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AmqpTemplate amqpTemplate;
    private static final String  KEY_PREFIX = "ly:user:verify:phone:";
    @Override
    public void sendCode(String phone) {
        // 验证手机号格式
        if (!RegexUtils.isPhone(phone)) {
            throw new LyException(ExceptionEnum.INVALID_PHONE_NUMBER);
        }

        // 生成验证码
        String code = RandomStringUtils.randomNumeric(6);

        // 保存验证码到redis     k  value  sijian  danwei
        redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 1, TimeUnit.MINUTES);

        // 发送RabbitMQ消息到ly-sms
        Map<String, String> msg = new HashMap<>();
        msg.put("phone", phone);
        msg.put("code", code);
      //  ObjectMapper mapper = new ObjectMapper();
   /*     try {
            String json = mapper.writeValueAsString(msg);
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setContentType("application/json");
            Message message = new Message(json.getBytes(),messageProperties);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }*/
            amqpTemplate.convertAndSend(SMS_EXCHANGE_NAME, VERIFY_CODE_KEY, msg);

    }
    //    redis key的前缀
    private String PRE_FIX = "ly:user:verify:phone:";


    @Autowired
    private BCryptPasswordEncoder passwordEncoder;//密码编译器

    public void register(TbUser user, String code) {
//        验证code，短信验证码
        String cacheCode = redisTemplate.opsForValue().get(PRE_FIX + user.getPhone());
        if(StringUtils.isEmpty(cacheCode) || !code.equals(cacheCode)){
            throw new LyException(ExceptionEnum.INVALID_VERIFY_CODE);
        }
//        处理用户密码
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        boolean b = this.save(user);
        if(!b){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /**
     * 根据用户名和密码查询用户
     * @param userName
     * @param passWord
     * @return
     */
    @Override
    public UserDTO queryUser(String userName, String passWord) {
//        根据用户名查询用户
        QueryWrapper<TbUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbUser::getUsername,userName);
        TbUser tbUser = this.getOne(queryWrapper);
        if(tbUser == null){
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
//        比对密码
        boolean b = passwordEncoder.matches(passWord, tbUser.getPassword());
        if(!b){
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
        return BeanHelper.copyProperties(tbUser,UserDTO.class);
    }
}
